home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / LANG / C / LIB / UNIXLIB37B / !UnixLib37 / src / stdio / c / popen < prev    next >
Text File  |  1996-11-09  |  3KB  |  179 lines

  1. /****************************************************************************
  2.  *
  3.  * $Source: /unixb/home/unixlib/source/unixlib37/src/stdio/c/RCS/popen,v $
  4.  * $Date: 1996/10/30 21:59:00 $
  5.  * $Revision: 1.3 $
  6.  * $State: Rel $
  7.  * $Author: unixlib $
  8.  *
  9.  * $Log: popen,v $
  10.  * Revision 1.3  1996/10/30 21:59:00  unixlib
  11.  * Massive changes made by Nick Burret and Peter Burwood.
  12.  *
  13.  * Revision 1.2  1996/05/06 09:01:34  unixlib
  14.  * Updates to sources made by Nick Burrett, Peter Burwood and Simon Callan.
  15.  * Saved for 3.7a release.
  16.  *
  17.  * Revision 1.1  1996/04/19 21:32:42  simon
  18.  * Initial revision
  19.  *
  20.  ***************************************************************************/
  21.  
  22. static const char rcs_id[] = "$Id: popen,v 1.3 1996/10/30 21:59:00 unixlib Rel $";
  23.  
  24. #include <errno.h>
  25. #include <stdlib.h>
  26. #include <stdio.h>
  27. #include <string.h>
  28. #include <unistd.h>
  29.  
  30. #include <sys/param.h>
  31. #include <sys/wait.h>
  32.  
  33. __STDIOLIB__
  34.  
  35. struct pwr
  36.   {
  37.     FILE *f;
  38.     int p0;
  39.     char *command;
  40.     struct pwr *next;
  41.   };
  42.  
  43. static struct pwr *__pwr = 0;
  44.  
  45. static void
  46. __pexec (const char *command)
  47. {
  48.   char *shell, *path;
  49.  
  50.   if (!(path = getenv ("SHELL")))
  51.     if (execl (command, "", 0))
  52.       _exit (1);
  53.  
  54.   shell = strrchr (path, '/');
  55.   if (shell)
  56.     shell++;
  57.   else
  58.     shell = path;
  59.   if (execl (path, shell, "-c", (char *) command, 0))
  60.     _exit (1);
  61. }
  62.  
  63. FILE *
  64. popen (const char *command, const char *mode)
  65. {
  66.   FILE *f;
  67.   int p[2];
  68.  
  69.   if (pipe (p) < 0)
  70.     return (0);
  71.  
  72.   if (*mode == 'r')
  73.     switch (fork ())
  74.       {
  75.       case -1:
  76.     close (p[0]);
  77.     close (p[1]);
  78.     return (0);
  79.     break;
  80.       case 0:
  81.     close (p[0]);
  82.     dup2 (p[1], 1);
  83.     close (p[1]);
  84.     __pexec (command);
  85.     break;
  86.       default:
  87.     close (p[1]);
  88.     if (!(f = fdopen (p[0], mode)))
  89.       return (0);
  90.     f->flag |= _IOPIPE;
  91.     return (f);
  92.     break;
  93.       }
  94.   else
  95.     {
  96.       FILE *f;
  97.       struct pwr *pwr;
  98.  
  99.       if (!(pwr = malloc (sizeof (struct pwr))))
  100.       return (0);
  101.       if (!(pwr->command = strdup (command)))
  102.     {
  103.       free (pwr);
  104.       return (0);
  105.     }
  106.       if (!(f = fdopen (p[1], mode)))
  107.     {
  108.       free (pwr);
  109.       free (pwr->command);
  110.       return (0);
  111.     }
  112.       f->flag |= _IOPIPE;
  113.       pwr->f = f;
  114.       pwr->p0 = p[0];
  115.       pwr->next = __pwr;
  116.       __pwr = pwr;
  117.       return (f);
  118.     }
  119.  
  120. /* never reached */
  121.  
  122.   return (0);
  123. }
  124.  
  125. int
  126. pclose (FILE * f)
  127. {
  128.   int r;
  129.  
  130.   if (!fispipe (f))
  131.     return (-1);
  132.  
  133.   if ((f->flag & _IOOMASK) == _IOWRITE)
  134.     {
  135.       struct pwr *pwr = __pwr, *pwr_ = 0;
  136.  
  137.       while (pwr)
  138.     {
  139.       if (pwr->f == f)
  140.         break;
  141.       pwr_ = pwr;
  142.       pwr = pwr->next;
  143.     }
  144.       if (!pwr)
  145.     return (-1);
  146.       if (pwr_)
  147.     pwr_->next = pwr->next;
  148.       else
  149.     __pwr = pwr->next;
  150.       fflush (f);
  151.       switch (fork ())
  152.     {
  153.     case -1:
  154.       close (pwr->p0);
  155.       close (f->fd);
  156.       return (-1);
  157.       break;
  158.     case 0:
  159.       close (f->fd);
  160.       dup2 (pwr->p0, 0);
  161.       close (pwr->p0);
  162.       __pexec (pwr->command);
  163.       break;
  164.     default:
  165.       close (pwr->p0);
  166.       break;
  167.     }
  168.       free (pwr->command);
  169.       free (pwr);
  170.     }
  171.  
  172.   r = (wait (0) >> 8);
  173.  
  174.   if (fclose (f))
  175.     return (-1);
  176.  
  177.   return (r);
  178. }
  179.